%{
#include <iostream>
#include <vector>
#include <stack>
#include <cstdlib>
#include <cstdio>
#include <cmath>

using namespace std;
stack <char> __calc_flex_operator_stack;
stack <double> __calc_flex_operand_stack;
char __calc_flex_operator;
double marker = 0 / 0.0;
int unrecognized_token = 0;
%}

%option noyywrap

digit [0-9]
operator [+\-*/]
operand [\+\-]*{digit}+
%%

{operator} {
        __calc_flex_operand_stack.push (marker);
        __calc_flex_operator_stack.push (yytext [0]);
      }

{operand} { 
        double __calc_flex_current_operand = (double) atoi (yytext);

        if (__calc_flex_operand_stack.size () == 0) {
            __calc_flex_operand_stack.push (__calc_flex_current_operand);
        } else if (__calc_flex_operand_stack.top () != __calc_flex_operand_stack.top ()) {
            __calc_flex_operand_stack.push (__calc_flex_current_operand);
        } else {
            double __calc_flex_operand2 = __calc_flex_current_operand;

            while ((__calc_flex_operand_stack.size () >= 2) 
                    && (__calc_flex_operator_stack.size ()) 
                    && (__calc_flex_operand_stack.top () == __calc_flex_operand_stack.top ())
                    ) {

                double __calc_flex_operand1 = 0;
                __calc_flex_operand1 = __calc_flex_operand_stack.top ();

                __calc_flex_operand_stack.pop ();
                __calc_flex_operand_stack.pop ();

                __calc_flex_operator = __calc_flex_operator_stack.top ();
                __calc_flex_operator_stack.pop ();

                if (__calc_flex_operator == '+')        __calc_flex_operand2 = (__calc_flex_operand1 + __calc_flex_operand2);
                else if (__calc_flex_operator == '-')   __calc_flex_operand2 = (__calc_flex_operand1 - __calc_flex_operand2);
                else if (__calc_flex_operator == '*')   __calc_flex_operand2 = (__calc_flex_operand1 * __calc_flex_operand2);
                else if (__calc_flex_operator == '/')   __calc_flex_operand2 = (__calc_flex_operand1 / __calc_flex_operand2);
                else if (__calc_flex_operator == '^')   __calc_flex_operand2 = (pow (__calc_flex_operand1, __calc_flex_operand2));
            }

            __calc_flex_operand_stack.push (__calc_flex_operand2);
        }
      }

[\n] { 
        if (unrecognized_token || __calc_flex_operand_stack.size () != 1 || __calc_flex_operator_stack.size ()) { 
            cerr << "syntax error" << endl;
        } else {
            printf ("%0.2f\n", __calc_flex_operand_stack.top ());
            __calc_flex_operand_stack.pop ();
        }

        while (__calc_flex_operator_stack.size ()) __calc_flex_operator_stack.pop ();
        while (__calc_flex_operand_stack.size ()) __calc_flex_operand_stack.pop ();
        unrecognized_token = 0;
     }

[ \t] ;

.    { 
        unrecognized_token = yytext [0];
        if (unrecognized_token) cerr << "unrecognized token: " << (char) unrecognized_token << endl;
      }
%%

int main (int argc, char *argv [])
{
    FlexLexer* lexer = new yyFlexLexer();
    while (lexer->yylex() != 0)
        ;

    return 0;
}
